use std::mem;
#[allow(dead_code)]
#[derive(Debug, Clone, Copy)]
struct Point {
    x: f64,
    y: f64,
}
#[allow(dead_code)]
struct Rectangle {
    p1: Point,
    p2: Point,
}

fn origin() -> Point {
    Point {x: 0.0, y: 0.0}
}
fn boxed_origin() -> Box<Point> {
//     在堆上分配这个点(point),并返回一个指向它的指针
    Box::new(Point {x: 0.0, y: 0.0})
}
fn main() {
//        所有的类型标注都不是必须的
//     栈分配的变量
    let point = origin();
    let rectangle = Rectangle {
        p1: origin(),
        p2: Point {x: 3.0, y: 4.0},
    };
//     堆分配的rectangle
    let boxed_rectangle = Box::new(Rectangle {
        p1: origin(),
        p2: origin(),
    });
//     函数的输出可以装箱
    let boxed_point = Box::new(origin());
//     两层的装箱
    let box_in_a_box = Box::new(boxed_origin());
    println!("未装箱的指针大小");
    println!("Point occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&point), &point);
    println!("Rectangle occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&rectangle), &rectangle);

//     box的宽度就是指针宽度
    println!("装箱的指针大小");
    println!("Boxed point occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&boxed_point), &boxed_point);
    println!("Boxed Rectangle occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&boxed_rectangle), &boxed_rectangle);
    println!("Boxed box occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&box_in_a_box), &box_in_a_box);

//     将包含在`boxed_point`中的数据复制到`unboxed_point1`中
    println!("将装箱的数据复制到未装箱的指针大小");
    let unboxed_point = *boxed_point;
    println!("Unboxed point occupies {} bytes in the stack, addr: {:p}", mem::size_of_val(&unboxed_point), &unboxed_point);
}
